/**
 * @file dbregroupement.c
 * @brief Fichier source du module database.
 *
 * @author Rachid Delory, Mamadou Keita, Florian Bernard
 */

/* *********************************************************************

                       Librairies de database                          

********************************************************************* */

#include "dbregroupement.h"

/* *********************************************************************

                        Fonctions                                      

********************************************************************* */

void recuperation_DReg(Arbre *arbre, const int id, const int level)
{
  if(!level)
    return;
  
  if(arbre)
    {
      DataBase data;
      ouvrir_Db();
      if(id == 0)
	{
	  /* Récupération de ceux qui n'ont pas de pere */
	  prepare_Db(&data, "select rowid, titre, type, illustration, commentaire, dateCreation from regroupement where rowid not in (select id_regroupement from regreg)");
	}
      else
	{
	  /* Récupération de ceux qui ont comme pere id */
	  prepare_Db(&data, "select rowid, titre, type, illustration, commentaire, dateCreation from regroupement where rowid in (select id_regroupement from regreg where id_parent = ?)");
	  bindValueInt_Db(&data, 1, id);
	}
      while(execute_Db(&data))
	{
	  Arbre *arb;
	  Regroupement reg;
	  Date *date = NULL;
	  init_Reg(&reg);
	  setId_Reg(&reg, getValueInt_Db(&data, 0));
	  setTitre_Reg(&reg, getValueText_Db(&data, 1));
	  setIllustration_Reg(&reg, getValueText_Db(&data, 3));
	  setCommentaire_Reg(&reg, getValueText_Db(&data, 4));
	  recuperation_DDat(&date, getValueInt_Db(&data, 5));
	  setCreation_Reg(&reg, date);
	  recuperation_DGen(getEnsembleGenre_Reg(&reg), getId_Reg(&reg), REGROUPEMENT_DGEN);
	  arb = creer_Arb(&reg);
	  ajoutNoeud_Arb(arbre, arb);
	  recuperation_DReg(getData_Ens(recupSousArbre_Arb(arbre)), getId_Reg(&reg), level - 1);
	  liberer_Reg(&reg);
	  detruire_Dat(&date);
	}
      finalise_Db(&data);
    }
}

void insertion_DReg(Arbre *arbre, Arbre *arbreParent)   
{
  if(arbre)
    {
      DataBase data;
      Regroupement *reg = getInformation(arbre);
      Ensemble *ensemble;
      int tailleEns, i;
      int nouveau = 0;
      ouvrir_Db();
      if(getInformation(arbre) != NULL)
	{
	  if(getSup_Reg(reg) == 1)
	    {
	      prepare_Db(&data, "delete from regroupement where rowid = ?");
	      bindValueInt_Db(&data, 1, getId_Reg(reg));
	    }
	  else if(getId_Reg(reg) == 0)
	    {
	      insertion_DDat(getCreation_Reg(reg));
	      prepare_Db(&data, "insert into regroupement (titre, type, illustration, commentaire, dateCreation) values (?, ?, ?, ?, ?)");
	    }
	  else
	    {
	      /* Update */
	      if(getMaj_Reg(reg) == 1)
		{
		  prepare_Db(&data, "update regroupement set titre = ?, type = ?, illustration = ?, commentaire = ?, dateCreation = ? where id = ?");
		  bindValueInt_Db(&data, 6, getId_Reg(reg));
		}
	    }
	  if((getMaj_Reg(reg) == 1 || getId_Reg(reg) == 0) && getSup_Reg(reg) == 0)
	    {
	      bindValueText_Db(&data, 1, getTitre_Reg(reg));
	      bindValueInt_Db(&data, 2, getType_Reg(reg));
	      bindValueText_Db(&data, 3, getIllustration_Reg(reg));
	      bindValueText_Db(&data, 4, getCommentaire_Reg(reg));
	      bindValueInt_Db(&data, 5, getId_Dat(getCreation_Reg(reg)));
	    }
	  if(getMaj_Reg(reg) == 1 || getId_Reg(reg) == 0 || getSup_Reg(reg) == 1)
	    {
	      if(execute_Db(&data))
		{
	  
		}
	      finalise_Db(&data);
	    }
	  if(getId_Reg(reg) == 0)
	    {
	      prepare_Db(&data, "select max(rowid) from regroupement");
	      if(execute_Db(&data))
		{
		  setId_Reg(reg, getValueInt_Db(&data, 0));
		  nouveau = 1;
		}
	      finalise_Db(&data);
	    }
	  /* Insertion dans la table regreg */
	  if(arbreParent)
	    {
	      if(getSup_Reg(getInformation(arbreParent)) == 1 || getSup_Reg(reg) == 1)
		{
		  prepare_Db(&data, "delete from regreg where id_parent = ? and id_regroupement = ?");
		}
	      else
		{
		  if(nouveau == 1 && 
		     getId_Reg(getInformation(arbreParent)) != 0)
		    {
		      prepare_Db(&data, "insert into regreg(id_parent, id_regroupement) values (?, ?)");
		    }
		}
	      if(getSup_Reg(getInformation(arbreParent)) == 1 || getSup_Reg(reg) == 1 || (nouveau == 1 && getId_Reg(getInformation(arbreParent)) != 0))
		{
		  bindValueInt_Db(&data, 1, getId_Reg(getInformation(arbreParent)));
		  bindValueInt_Db(&data, 2, getId_Reg(reg));
		  if(execute_Db(&data))
		    {
		  
		    }
		  finalise_Db(&data);
		}
	    }
	}
      /* Insertion des sous arbres */
      ensemble = recupSousArbre_Arb(arbre);
      tailleEns = getTaille_Ens(ensemble);
      prems_Ens(ensemble);
      for(i = 0; i < tailleEns; i++)
	{
	  if(getSup_Reg(reg) == 1)
	    {
	      setSup_Reg(getInformation(getData_Ens(ensemble)), 1);
	    }
	  insertion_DReg(getData_Ens(ensemble), arbre);
	  suivant_Ens(ensemble);
	}
      /* Insertion des feuilles */
      ensemble = recupFeuille_Arb(arbre);
      tailleEns = getTaille_Ens(ensemble);
      prems_Ens(ensemble);
      for(i = 0; i < tailleEns; i++)
	{
	  int nouveau;
	  if(getSup_Reg(reg) == 1)
	    {
	      setSup_Oeu(getData_Ens(ensemble), 1);
	    }
	  nouveau = getId_Oeu(getData_Ens(ensemble));
	  insertion_DOeu(getData_Ens(ensemble));
	  if(getSup_Reg(reg) == 0)
	    {
	      if(nouveau == 0)
		{
		  prepare_Db(&data, "insert into regroupementOeuvre(id_regroupement, id_oeuvre) values (?, ?)");
		}
	    }
	  else
	    {
	      prepare_Db(&data, "delete from regroupementOeuvre where id_regroupement = ? and id_oeuvre = ?");	      
	    }
	  if(nouveau == 0 || getSup_Reg(reg) == 1)
	    {
	      bindValueInt_Db(&data, 1, getId_Reg(reg));
	      bindValueInt_Db(&data, 2, getId_Oeu(getData_Ens(ensemble)));
	      if(execute_Db(&data))
		{
		  
		}
	      finalise_Db(&data);
	    }
	  suivant_Ens(ensemble);
	}
      /* Insertion des genres */
      {
	if(getSup_Reg(reg) == 1)
	  {
	    prepare_Db(&data, 
		       "delete from regroupementgenre where id_regroupement = ?");
	    bindValueInt_Db(&data, 1, getId_Reg(reg));
	    if(execute_Db(&data))
	      {
	      }
	    finalise_Db(&data);
	  }
	else
	  {
	    Ensemble *ens;
	    int tailleEns, i;
	    ens = getEnsembleGenre_Reg(reg);
	    tailleEns = getTaille_Ens(ens);
	    prems_Ens(ens);
	    for(i = 0; i < tailleEns; i++)
	      {
		if(getSup_Ens(ens) == 1)
		  prepare_Db(&data, "delete from regroupementgenre where id_regroupement = ? and id_genre = ?");
		else if(getMaj_Ens(ens) == 1)
		  prepare_Db(&data, "insert into regroupementgenre (id_regroupement, id_genre) values ( ?, ?)");
		if(getMaj_Ens(ens) == 1 || getSup_Ens(ens) == 1)
		  {
		    bindValueInt_Db(&data, 1, getId_Reg(reg));
		    bindValueInt_Db(&data, 2, getId_Gen(getData_Ens(ens)));
		    if(execute_Db(&data))
		      {
		      }
		    finalise_Db(&data);
		  }
		suivant_Ens(ens);
	      }
	  }
      }
    }
}

void setVue_DReg(Arbre* arbre, const int b)
{  
  if(arbre)
    {
      DataBase data;
      Regroupement *reg = getInformation(arbre);
      Ensemble *ens = recupSousArbre_Arb(arbre);
      int taille = getTaille_Ens(ens);
      int i;
      prems_Ens(ens);
      
      prepare_Db(&data, "update oeuvre set NbVisio = ? where id in (select id_oeuvre from regroupementOeuvre where id_regroupement = ?)");

      bindValueInt_Db(&data,1,b);
      bindValueInt_Db(&data,2,getId_Reg(reg));
      if (execute_Db(&data))
	{
	}
      finalise_Db(&data);

      for (i=0; i < taille; i++)
	{
	  setVue_DReg(getData_Ens(ens), b);
	  suivant_Ens(ens);
	}
    } 
}

void regression_DReg()
{
  Arbre *arb = creer_Arb(NULL);
  Ensemble *reg;
  int i, j;
  ouvrir_Db();
  
  recuperation_DReg(arb, 0, 1);
  reg = recupSousArbre_Arb(arb);
  j = getTaille_Ens(reg);
  prems_Ens(reg);
  for(i = 0; i < j ; i++)
    {
      recuperation_DReg(getData_Ens(reg), getId_Reg(getInformation(getData_Ens(reg))), 1);
      suivant_Ens(reg);
    }
  printf("Hauteur : %d\n", hauteur_Arb(arb));
  printf("Voici la récupération : \n");
  afficher_Arb(arb, 1);
  detruire_Arb(&arb);
  fermer_Db();
}
